const objectId = require('bson-objectid');
const async = require('async');
const LoopBackContext = require('loopback-context');
const services = require('../../services');
const enums = require('../../enums');

const commonService = services.common;
const eLancoService = services.eLanco;

module.exports = (req, res, callback) => {
  const context = LoopBackContext.getCurrentContext();
  const form = context.get('form');
  const flow = context.get('flow');
  const formId = req.body.formId;
  let id = req.params.id == 0 ? null : req.params.id;
  const data = req.body.formDetail;
  const { WfRunInstance: formDetailModel, WfRunFlowDetail: approvalDetailModel } = commonService.getModels();
  const deleteApprovalList = (next) => {
    approvalDetailModel.updateAll({ instanceId: id }, { deleted: true }, error => next(error));
  };
  const saveFormDetail = (next) => {
    formDetailModel.upsert({
      id,
      formId,
      flowId: flow.id,
      historyId: req.body.historyId || objectId(),
      formNumber: req.body.formNumber || eLancoService.getFormNumber(form.formNumber),
      formStatus: enums.formStatus.submitted,
      approvalStep: 1,
      formDetail: data,
      requestDate: Date.now(),
    }, next);
  };
  const getApprovalList = (formDetail, next) => {
    id = formDetail.id;
    context.set('formDetail', formDetail);
    if (flow.flowRun.isDynamicFlow) {
      eLancoService.getDynamicFlowApprovalList(form, formDetail, formDetail.approvalStep, (error, approvalFinalStep, approvalList) => next(error, approvalFinalStep, approvalList));
    } else {
      eLancoService.getStaticFlowApprovalList(form, formDetail, next);
    }
  };
  const createApprovalList = (approvalFinalStep, approvalList, next) => {
    approvalDetailModel.create(approvalList, (error, approvalList) => next(error, approvalFinalStep, approvalList));
  };
  const saveFormDetailApprovalFinalStep = (approvalFinalStep, approvalList, next) => {
    formDetailModel.upsert({
      id,
      approvalFinalStep,
    }, next);
  };
  const getFormDetail = (formDetail, next) => {
    eLancoService.getFormDetailIncludeAll(formId, id, (error, formDetail) => {
      context.set('formDetail', formDetail);
      context.set('approvalList', formDetail.approvalList());
      next(error, formDetail);
    });
  };
  async.waterfall([deleteApprovalList, saveFormDetail, getApprovalList, createApprovalList, saveFormDetailApprovalFinalStep, getFormDetail], callback);
};
